
//
//
//  This tool will read ARToolKit pattern files (with variable size) and save
//  them as Portable Pixmap (.ppm) files.
//
//  Usage: PATT_to_PPM [infilename] [outfilename] [width] [height]
//
//
//  Thanks to Antonio Bleile for contributing the PPM writer code
// 


#include <stdio.h>
#include <assert.h>
#include <stdlib.h>



char
skipSpaces(FILE* fp)
{
	char ch = ' ';

	while( ch==' ' && !feof(fp))
		ch = fgetc(fp);

	return ch;
}


bool
readNumber(FILE* fp, char* buffer, int maxLen)
{
	char ch = 0;
	int i=0;

	do {
		ch = fgetc(fp);
		if(ch>='0' && ch<='9')
			buffer[i++] = ch;
	} while(!feof(fp) && i<maxLen-1 && ch!=' ');


	buffer[i++] = 0;
	return i<maxLen && !feof(fp);
}


bool
writePPM( const char *fileName, unsigned char *data, int width, int height )
{
	FILE *file = fopen( fileName, "wb" );
	if( !file ){
		printf( "Could not open file %s for writing\n", fileName );
		return false;
	}

	// error checking omitted
	fprintf( file, "P6\n# generated by patt_to_ppm\n%d %d\n255\n", width, height );
	fwrite( data, width*height*3, 1, file );

	fclose( file );

	return true;
}


unsigned char *
readMarkerFile(const char* nFileName, int nMarkerWidth, int nMarkerHeight)
{
	FILE* fp = fopen(nFileName, "r");

	if(!fp)
		return NULL;

	const int strMax = 256, numPix = nMarkerWidth*nMarkerHeight;
	unsigned char* pixels24 = new unsigned char[numPix*3];
	char str[strMax+1];
	int x,y,channel;

	for(channel=0; channel<3; channel++)
		for(y=0; y<nMarkerHeight; y++)
		{
			for(x=0; x<nMarkerWidth; x++)
			{
				str[0] = skipSpaces(fp);
				readNumber(fp, str+1, strMax);
				int value = atoi(str);
				int offset = 3*(x + y*nMarkerWidth) + channel;
				assert(offset < numPix*3);
				pixels24[offset] = value;
			}
		}


	fclose(fp);

	return pixels24;
}


int main(int argc, char** argv)
{
	unsigned char *patternImage;
	int width = 16, height = 16;

	if(argc<3)
	{
		printf("ERROR: to few parameters\n");
		printf("Usage: %s infilename outfilename [width=16] [height=16]\n", argv[0] );
		printf("Example: %s patt.hiro patt_hiro.ppm 32 32\n", argv[0] );
		return -1;
	}

	const char	*inName = argv[1],
				*outName = argv[2];

	if( argc >= 4 )
		width = atoi( argv[3] );
	if( argc >= 5 )
		height = atoi( argv[4] );

	patternImage = readMarkerFile(inName, width,height);

	if( patternImage )
		writePPM( outName, patternImage, width, height );

	return 0;
}
